// 职责链模式的定义是：使用多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系，将这些对象链成一条链，并沿着这条链传递该请求，知道有一个对象处理它为止。

// 优点：
// 1 降低耦合度，它将请求的发送者和接收者解耦。
// 2 简化了对象，使得对象不需要知道链的结构。
// 3 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序，允许动态地新增或者删除责任。

// 缺点：
// 1 不能保证每一条请求都一定被接收。
// 2 系统性能将受到一定影响，而且在进行代码调试时不太方便，可能会造成循环调用。
// 3 可能不容易观察运行时的特征，有碍于排除问题。

// 例子：
// 假设我们负责一个手机售卖的电商网站，分别缴纳500元和200元定金的两轮预订后，会分别收到100元和50元的优惠券，而没有支付定金的则视为普通购买，没有优惠券，并且在库存有限的情况下也无法保证能购买到。
class Order500 {
  constructor() {
    this.orderType = 1;
  }
  handle(orderType, pay, stock) {
    if (orderType === this.orderType && pay) {
      console.log('500元定金预约，得到100元优惠券');
    } else {
      return 'nextSuccessor';
    }
  }
}
class Order200 {
  constructor() {
    this.orderType = 2;
  }
  handle(orderType, pay, stock) {
    if (orderType === this.orderType && pay) {
      console.log('200元订金预约，得到50元优惠卷');
    } else {
      return 'nextSuccessor';
    }
  }
}
class OrderNormal {
  constructor() {
    this.stock = 0;
  }
  handle(orderType, pay, stock) {
    if (stock > this.stock) {
      console.log('普通购买，无优惠卷');
    } else {
      console.log('手机库存不足');
    }
  }
}

class Chain {
  constructor(order) {
    this.order = order;
    this.successor = null;
  }
  setNextSuccessor(successor) {
    return (this.successor = successor);
  }
  passRequest(...val) {
    const ret = this.order.handle.apply(this.order, val);
    if (ret === 'nextSuccessor') {
      return (
        this.successor && this.successor.passRequest.apply(this.successor, val)
      );
    }
    return ret;
  }
}
console.log(new Order500());
var chainOrder500 = new Chain(new Order500());
var chainOrder200 = new Chain(new Order200());
var chainOrderNormal = new Chain(new OrderNormal());

chainOrder500.setNextSuccessor(chainOrder200);
chainOrder200.setNextSuccessor(chainOrderNormal);

chainOrder500.passRequest(1, true, 500); // 输出：500 元定金预购，得到 100 优惠券
chainOrder500.passRequest(2, true, 500); // 输出：200 元定金预购，得到 50 优惠券
chainOrder500.passRequest(3, true, 500); // 输出：普通购买，无优惠券
chainOrder500.passRequest(1, false, 0); // 输出：手机库存不足
